home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / vmed.arc / ED3.CCC < prev    next >
Text File  |  1985-12-03  |  15KB  |  715 lines

  1. /*    Screen editor:    command mode commands
  2.  *
  3.  *    Module: ed3/ccc
  4.  *    Date: November 12, 1983
  5.  *    Changed: February 18, 1984 (corrected LIST cmd, added
  6.  *                loading and saving mode messages)
  7.  *    Changed: February 29, 1984 (added VMED.002 stuff)
  8.  *    Changed: March 8, 1984 (bufatbot() refs)
  9.  */
  10.  
  11. #include ed0
  12.  
  13. /* data global to this module */
  14.  
  15. #option zvar ON
  16. int        pastefile; 
  17. #option zvar OFF
  18. char    filename[SYSFNMAX],
  19.         patxx[MAXLEN1];    /* reserve space for EOS */
  20.  
  21. /* append command.
  22.  * load a file into main buffer at current location.
  23.  * this command does NOT change the current file name
  24.  */
  25. append(args)    char    *args;
  26. {     char    buffer[MAXLEN],        /* disk line buffer */
  27.             locfn[SYSFNMAX];    /* local file name */
  28.     int        n,topline;
  29.     FILE    *file;
  30. /* get file name which follows command */
  31.     if (name1(args,locfn)==ERR)
  32.         return;
  33.     if (locfn[0]==EOS)     {
  34.         outm(noarg);
  35.         return;
  36.     }
  37. /* open new file */
  38.     pmtmode("append:");
  39.     if ((file=sysopen(locfn,"r"))==ERR)    {
  40.         outm(filenot);
  41.         return;
  42.     }
  43. /* read the file into the buffer */
  44.     for (; (n=readline(file,buffer,MAXLEN)) >= 0; pmtlnx())
  45.         if(store(buffer,n) == ERR)
  46.             break;
  47. /* close the file */
  48.     sysclose(file);
  49. /* redraw the screen so topline will be at top
  50.  * of the screen after command() does a CR/LF.
  51.  */
  52.     topline=max(1,bufln()-SCRNL2);
  53.     bufout(topline,2,SCRNL2);
  54.     bufgo(topline);
  55. }
  56.  
  57. /* clear main buffer and file name */
  58. clear()
  59. {     /* make sure it is ok to clear buffer */
  60.     if (chkbuf()!=YES)
  61.         return;
  62.     pmtfile("");
  63.     filename[0]=0;
  64.     outclr();
  65.     outxy(0,SCRNL1);
  66.     bufnew();
  67. }
  68.  
  69. /* multiple line delete command */
  70. delete(args)    char    *args;
  71. {     int    from,to;
  72.     /* make sure there ARE arguments */
  73.     default(args,".,.");
  74.     if (get2args(args,&from,&to)==ERR || from>to)
  75.         return;
  76. /* go to first line to be deleted */
  77.     if (bufgo(from)==ERR)
  78.         return;
  79. /* delete all lines between from and to */
  80.     if (bufdeln(to-from+1)==ERR)
  81.         return;
  82. /* redraw the screen */
  83.     bufout(bufln(),1,SCRNL1);
  84. }
  85.  
  86. /* list lines to list device */
  87. list(args)    char    *args;
  88. {     char    linebuf[MAXLEN1],temp;
  89.     int    n,from,to,oldline;
  90. /* save the buffer's current line */
  91.     oldline=bufln();
  92. /* get starting, ending lines to print */
  93.     if (get2args(args,&from,&to)==ERR)
  94.         return;
  95.     to = min(to,buffree());
  96. /* print lines one at a time to list device */
  97.     while (in_txt() && from<=to)    {
  98. /* check for interrupt */
  99.         if (chkkey()==YES)
  100.             break;
  101. /* print line to list device */
  102.         if (bufgo(from++) || past_eof())    /* 3-8-84 */
  103.             break;
  104.         n = bufgetln(linebuf,MAXLEN1);
  105.         n=min(n,MAXLEN);
  106.         linebuf[n]=CR;
  107.         fmtsout(linebuf,0);
  108.         fmtcrlf();
  109.      }
  110. /* restore cursor */
  111.     bufgo(oldline);
  112. }
  113.  
  114. /* display a line number and line */
  115. dspline(linebuf)    int    linebuf;
  116. {    putdec(bufln(),0);
  117.     fmtsout(":",outgety());
  118.     fmtsout(linebuf,8);
  119.     outdeol();
  120.     fmtcrlf();
  121. }
  122.  
  123. /* load file into buffer */
  124. load(args)    char    *args;
  125. {     char    buffer[MAXLEN],        /* disk line buffer */
  126.             locfn[SYSFNMAX];
  127.     int        n,topline;
  128.     FILE    *file;
  129. /* get filename following command */
  130.     if (name1(args,locfn)==ERR)
  131.         return(NO);
  132.     if (locfn[0]==EOS)     {
  133.         outm(noarg);
  134.         return(NO);
  135.     }
  136. /* give user a chance to save the buffer */
  137.     if (chkbuf()==NO)
  138.         return(NO);
  139. /* open the new file */
  140.     pmtmode("loading:");
  141.     if ((file=sysopen(locfn,"r"))==ERR)     {
  142.         outm(filenot);
  143.         return(NO);
  144.     }
  145. /* update file name */
  146.     syscopfn(locfn,filename);
  147. /* clear the buffer */
  148.     bufnew();
  149.     pmtfile(filename);
  150. /* read the file into the buffer */
  151.     for (; (n=readline(file,buffer,MAXLEN)) >= 0; pmtlnx())
  152.         if(store(buffer,n)==ERR)
  153.             break;
  154. /* close the file */
  155.     sysclose(file);
  156. /* indicate that the buffer is fresh */
  157.     bufsaved();
  158. /* set current lin to line 1 */
  159.     bufgo(1);
  160. /* redraw the screen so that topline will be on line 1
  161.  * after command() does a CR/LF.
  162.  */
  163.     topline=max(1,bufln()-SCRNL2);
  164.     bufgo(topline);
  165.     return(YES);
  166. }
  167.  
  168. /* change current file name */
  169. name(args)    char    *args;
  170. {     name1(args,filename);
  171.     pmtfile(filename);
  172. }
  173.  
  174. /* check syntax of args.
  175.  * copy to filename.
  176.  * return OK if the name is valid.
  177.  */
  178. name1(args,filename)    char    *args,*filename;
  179. {     /* skip command */
  180.     args=skiparg(args);
  181.     args=skipbl(args);
  182. /* check file name syntax */
  183.     if (syschkfn(args)==ERR)
  184.         return(ERR);
  185. /* copy filename */
  186.     syscopfn(args,filename);
  187.     return(OK);
  188. }
  189. /* check the length of a line */
  190. chklen(n)    char    n;
  191. {     if (n>MAXLEN)     {
  192.         outm(linetrun);
  193.         n=MAXLEN;
  194.     }
  195.     return(n);
  196. }
  197.  
  198. /* store a line in the buffer */
  199. store(buff,count)    int buff;    char count;
  200. {     count = chklen(count);
  201.     if (bufins(buff,count)==ERR)
  202.         return(ERR);
  203.     if (bufdn()==ERR)
  204.         return(ERR);
  205.     return(OK);
  206. }
  207.  
  208. /* set tab stops for fmt routines */
  209. tabs(args)    char *args;
  210. {     int    n;
  211.     if (number(skipbl(skiparg(args)),&n) == NO)
  212.         return;
  213.     fmtset(n);
  214. }
  215.  
  216. /* return YES if buffer may be drastically changed */
  217. chkbuf()
  218. {     if (bufchng()==NO)
  219.         return(YES);    /* buffer unchanged. no problem */
  220.     fmtsout("buffer not saved. proceed ? ",0);
  221.     pmtline();
  222.     if (tolower(syscout(syscin()))!='y')     {
  223.         fmtcrlf();
  224.         outm(cancel);
  225.         return(NO);
  226.     }
  227.     /*else*/
  228.     fmtcrlf();
  229.     return(YES);
  230. }
  231.  
  232. /* get two arguments from the argument line 'args'.
  233.  * no arguments imply 1 HUGE.
  234.  * one argument implies both args the same.
  235.  */
  236. get2args(args,val1,val2)    char *args;    int *val1,*val2;
  237. {    /* skip over the command */
  238.     args=skiparg(args);
  239.     args=skipbl(args);
  240.     if (*args==EOS)    {
  241.         *val1=1;
  242.         *val2=buffree();        /* 3-7-84 */
  243.         return(OK);
  244.     }
  245. /* check first argument */
  246.     if (number(args,val1)==NO)    {
  247.         outm(badarg);
  248.         return(ERR);
  249.     }
  250. /* skip over first argument */
  251.     args=skiparg(args);
  252.     args=skipbl(args);
  253. /* 1 arg; arg 2 is same */
  254.     if (*args==EOS)    {
  255.         *val2=*val1;
  256.         return(OK);
  257.     }
  258. /* check second argument */
  259.     if (number(args,val2)==NO)    {
  260.         outm(badarg);
  261.         return(ERR);
  262.     }
  263.     else    return(OK);
  264. }
  265.  
  266. /* skip over all except EOS, commas, and blanks */
  267. skiparg(args)    char *args;
  268. {    while (*args!=EOS && *args!=' ' && *args!=',')
  269.         ++args;
  270.     return(args);
  271. }
  272.  
  273. /* skip over all blanks and commas */
  274. skipbl(args)    char *args;
  275. {    while (*args==' ' || *args==',')
  276.         ++args;
  277.     return(args);
  278. }
  279.  
  280. /* global change command */
  281. change(args)    char    *args;
  282. {     char    oldline[MAXLEN1],
  283.             newline[MAXLEN1],
  284.             oldpat[MAXLEN1],
  285.             newpat[MAXLEN1],
  286.             flag;
  287.     int    from,to,col,n,k,temp;
  288.     if (get2args(args,&from,&to)==ERR)
  289.         return;
  290.     flag = 1;
  291. /* get search and change masks into oldpat, newpat */
  292.     outm(smask);
  293.     getcmnd(oldpat,15);
  294.     fmtcrlf();
  295.     if (oldpat[0]==EOS)
  296.         return;
  297.     pmtline();
  298.     fmtsout("change mask ? ",0);
  299.     getcmnd(newpat,15);
  300.     fmtcrlf();
  301.     temp = bufln();
  302.     to = min(to,buffree());
  303. /* make substitution for lines between from, to */
  304.     while (from <= to)     {
  305.         if (chkkey() || bufgo(from++)==EOF)
  306.             break;                /* 3-8-84 */
  307.         n=bufgetln(oldline,MAXLEN);
  308.         n=min(n,MAXLEN);
  309.         oldline[n]=EOS;
  310. /* '^' anchors search */
  311.         if (oldpat[0]=='^')
  312.             if (amatch(oldline,oldpat+1,0)==YES)    {
  313.                 k=replace(oldline,newline,oldpat+1,newpat,0);
  314.                 if (k==ERR)
  315.                     return;
  316.                 flag = 0;
  317.                 dspline(newline);
  318.                 bufrepl(newline,k);
  319.                 continue;
  320.              }
  321. /* search oldline for oldpat */
  322.         col=0;
  323.         while (col<n)
  324.             if (amatch(oldline,oldpat,col++)==YES)     {
  325.                 k=replace(oldline,newline,oldpat,newpat,col-1);
  326.                 if(k==ERR)
  327.                     return;
  328.                 flag = 0;
  329.                 dspline(newline);
  330.                 bufrepl(newline,k);
  331.                 break;
  332.             }
  333.     pmtmode("changing:");
  334.      }
  335.     bufgo(temp);
  336.     if(flag)
  337.         outm(patnotfnd);
  338. }
  339.  
  340. /* search all lines below the current line for a pattern
  341.  * return -1 if pattern not found
  342.  * otherwise, return column number of start of pattern
  343.  */
  344. find()
  345. {     return(search1(bufln()+1,buffree(),YES)); }
  346.  
  347. /* global search command */
  348. search(args)    char *args;
  349. {     int    from,to;
  350.     if (get2args(args,&from,&to)==ERR)
  351.         return;
  352.     search1(from,to,NO);
  353. }
  354.  
  355. /* search lines for a pattern.
  356.  * if flag == YES:    stop at the first match.
  357.  *            return -1 if no match.
  358.  *            otherwise return column number of match.
  359.  * if flag == NO:    print all matches found.
  360.  */
  361. search1(from,to,flag)    int from,to;    char flag;
  362. {     char    line[MAXLEN1];
  363.     int    col,n;
  364. /* get search mask into pat */
  365.     outm(smask);
  366.     getcmnd(patxx,15);
  367.     fmtcrlf();
  368.     if (patxx[0]==EOS)
  369.         return;
  370.     to = min(to,buffree());
  371.     pmtmode("searching:");
  372. /* search all lines between from and to for pat */
  373.     while (from<=to)     {
  374.         if (chkkey()==YES ||
  375.             bufgo(from++)==EOF)
  376.                 break;
  377.         n=bufgetln(line,MAXLEN);
  378.         n=min(n,MAXLEN);
  379.         line[n]=EOS;
  380.         pmtlnx();
  381. /* ^ anchors search */
  382.         if (patxx[0]=='^')    {
  383.             if (amatch(line,patxx+1,0)==YES)    {
  384.                 if (flag==NO)
  385.                     dspline(line);
  386.                 else    return(0);
  387.             }
  388.             continue;
  389.         }
  390. /* search whole line for match */
  391.         col=0;    
  392.         while (col<n)
  393.             if (amatch(line,patxx,col++)==YES)
  394.                 if (flag==NO)    {
  395.                     dspline(line);
  396.                     break;
  397.                 }
  398.                 else    return(col-1);
  399.     }
  400. /* all searching is finished */
  401.     if (flag==YES)
  402.         return(-1);
  403.     else    fmtcrlf();
  404. }
  405.  
  406. /* search for next occurance of pattern from edit mode */
  407. srch1()
  408. {    char    line[MAXLEN1];
  409.     int    col,n,old,from,to;
  410.     old = bufln();
  411.     from = old + 1;
  412.     to = buffree();
  413.     pmtmode("searching:");
  414. /* search all lines between from and to for pat */
  415.     while (from <= to)    {        /* 6-17-84 */
  416.         if (bufgo(from++)==EOF)
  417.             break;            /* 3-8-84 */
  418.         n=bufgetln(line,MAXLEN);
  419.         n=min(n,MAXLEN);
  420.         line[n]=EOS;
  421.         pmtlnx();
  422. /* ^ anchors search */
  423.         if (patxx[0]=='^')    {
  424.             if (amatch(line,patxx+1,0)==YES)    {
  425.                 edgo(bufln(),0);
  426.                 return;
  427.             }
  428.             continue;
  429.         }
  430. /* search whole line for match */
  431.         col=0;    
  432.         while (col<n)
  433.             if (amatch(line,patxx,col++)==YES)    {
  434.                 edgo(bufln(),col-1);
  435.                 return;
  436.             }
  437.     }
  438.     bufgo(old);
  439. }
  440.  
  441.  
  442. /* return YES if the user has pressed any key.
  443.  * blanks cause a tranparent pause.
  444.  */
  445. chkkey()
  446. {    char    c;
  447.     c=syscstat();
  448.     if (c==0)
  449.         return(NO);    /* no character at keyboard */
  450.     else if (syscin()==' ')    {
  451. /* pause. another blank ends pause */
  452.         pmtline();
  453.         while (!syscstat())            /* modified 3-7-84 */
  454.             ;
  455.         if (syscin()==' ')
  456.             return(NO);
  457.     }
  458. /* we got a nonblank character */
  459.     return(YES);
  460. }
  461.  
  462. /* anchored search for pattern in text line at column col.
  463.  * return YES if the pattern starts at col.
  464.  */
  465. amatch(line,pat,col)    char *line,*pat;    int col;
  466. {    int    k;
  467.     k=0;
  468.     while(pat[k]!=EOS)    {
  469.         if (pat[k]==line[col])    {
  470.             ++k;
  471.             ++col;
  472.         }
  473.         else if ((pat[k]=='?')&(line[col]!=EOS))    {
  474. /* question mark matches any character */
  475.             ++k;
  476.             ++col;
  477.         }
  478.         else    return(NO);
  479.     }
  480. /* the entire pattern matches */
  481.     return(YES);
  482. }
  483.  
  484. /* replace oldpat in oldline by newpat starting at col.
  485.  * put result in newline.
  486.  * return number of characters in newline.
  487.  */
  488. replace(oldline,newline,oldpat,newpat,col)
  489. char    *oldline,*newline,*oldpat,*newpat;
  490. int    col;
  491. {    int    k;
  492.     char    *tail,*pat;
  493. /* copy oldline preceding col to new line */
  494.     k=0;
  495.     while(k<col)
  496.         newline[k++]=*oldline++;
  497. /* remember where end of oldpat in oldline is */
  498.     tail=oldline;
  499.     pat=oldpat;
  500.     while(*pat++!=EOS)
  501.         ++tail;
  502. /* copy newpat to newline.
  503.  * use oldline and oldpat to resolve question marks
  504.  * in newpat.
  505.  */
  506.     while(*newpat!=EOS)    {
  507.         if (k>MAXLEN-1)    {
  508.             outm(nltolong);
  509.             return(ERR);
  510.         }
  511.         if (*newpat!='?')    {
  512. /* copy newpat to newline */
  513.             newline[k++]=*newpat++;
  514.             continue;
  515.         }
  516. /* scan for '?' in oldpat */
  517.         while (*oldpat!='?')    {
  518.             if (*oldpat==EOS)    {
  519.                 outm(toomany);
  520.                 return(ERR);
  521.             }
  522.             ++oldpat;
  523.             ++oldline;
  524.         }
  525. /* copy char from oldline to newline */
  526.         newline[k++]=*oldline++;
  527.         ++oldpat;
  528.         ++newpat;
  529.     }
  530. /* copy oldine after oldpat to newline */
  531.     while(*tail!=EOS)    {
  532.         if (k>=MAXLEN-1)    {
  533.             outm(nltolong);
  534.             return(ERR);
  535.         }
  536.         newline[k++]=*tail++;
  537.     }
  538.     newline[k]=EOS;
  539.     return(k);
  540. }
  541.  
  542. /* copy lines from one part of file to another
  543.  * source lines are deleted if flag == YES
  544.  */
  545. copy(args,flag)
  546. char    *args;
  547. int        flag;
  548. {
  549.     int    start,linend,to,new,diff;
  550.     /* Skip command */
  551.     args = skipbl(skiparg(args)); 
  552.     /* were there arguments? */
  553.     if (*args != EOS){
  554.         if (number(args,&start) == ERR) return;
  555.         if (get2args(args,&linend,&to) == ERR) return;
  556.         }
  557.     else {        /* no, prompt for them */
  558.         start = getnum("Start");
  559.         linend = getnum("End");
  560.         to = getnum("To");
  561.         }
  562.     /* Check if "to" is within "start" to "linend" */
  563.     if ((start <= to) & (linend >= to)){    /* fixes bug from original code */
  564.         outm(flag ? badmove : badcopy);
  565.         return;
  566.         }
  567.     new = bufln();
  568.     if (writefile("VM/MOV","w",start,linend) == ERR) return;
  569.     if (bufgo(to) == ERR) return;
  570.     append(" VM/MOV");
  571.     diff = linend - start + 1;
  572.  
  573.     /* if this was a "move", we need to delete the old lines
  574.      * otherwise, just restore the line counter to old line
  575.      */
  576.     if (flag == YES){
  577.         if (start > to) start += diff;
  578.         if (bufgo(start) == ERR) return;
  579.         if (bufdeln(diff) == ERR) return;
  580.         }
  581.     else    if (new > to) new += diff;
  582.     bufgo(new);
  583. }
  584.  
  585. /* get number handler. get a
  586.  * line number from user
  587.  */
  588. getnum(ptr)    char *ptr;
  589. {    int    numb;
  590.     char    buf[MAXLEN1];
  591.     fmtsout(ptr,0);
  592.     fmtsout(" line: ",0);
  593.     getcmnd(buf,15);        /* get the answer */
  594.     number(buf,&numb);        /* copy the answer into 'numb' */
  595.     fmtcrlf();
  596.     return(numb);
  597. }
  598.  
  599. /* paste from VM/PST to present position */
  600. paste()
  601.     {
  602.     append(" VM/PST");
  603.     pastefile = 0;
  604.     }
  605.  
  606. /* save entire file */
  607. save(args)
  608. char *args;
  609. {
  610.     pmtmode("saving:");
  611.     /* default to file in header line */
  612.     default(args,filename);
  613.     args = skipbl(skiparg(args));
  614.     if (writefile(args,"w",1,buffree()) != ERR)
  615.     bufsaved();
  616. }
  617.  
  618. /* keep a portion of workfile to VM/PST */
  619. keep(args)
  620. char    *args;
  621. {
  622.     int    start,linend;
  623.     char    *mode;
  624.     mode = (pastefile ? "a" : "w");
  625.     /* default to current line only */
  626.     default(args,".,.");
  627.     if (get2args(args,&start,&linend) == ERR){
  628.         outm(badarg);
  629.         return;
  630.         }
  631.     pmtmode("writing:");
  632.     writefile("VM/PST",mode,start,linend);
  633.     pastefile = 1;
  634. }
  635.  
  636. /* "put" a part of the working file to the named file */
  637. putfile(args)
  638. char    *args;
  639. {
  640.     int    start,linend;
  641.     args = skipbl(skiparg(args));
  642.     if (*args == EOS){
  643.         outm(noarg);
  644.         return;
  645.         }
  646.     start = getnum("Start");
  647.     linend = getnum("End");
  648.     pmtmode("writing:");
  649.     writefile(args,"w",start,linend);
  650. }
  651.  
  652. /* write the specified lines to the specified file */
  653. writefile(args,mode,start,linend)
  654. char    *args,*mode;
  655. int        start,linend;
  656. {
  657.     int        oldline,n;
  658.     char    linebuf[MAXLEN];
  659.     FILE    *file;
  660.     /* keep from outputting beyond workfile's end */
  661.     linend = min(linend,buffree());
  662.     if (linend < start){
  663.         outm(backwards);
  664.         return(ERR);
  665.         }
  666.     else if (*args == EOS){
  667.         outm(noarg);
  668.         return(ERR);
  669.         }
  670.     else if ((file = sysopen(args,mode)) == ERR)
  671.         return(ERR);
  672.     /* remember old line number */
  673.     oldline = bufln();
  674.     /* write file */
  675.     if (bufgo(start) == ERR){
  676.         sysclose(file);
  677.         return(ERR); 
  678.         }
  679.     while(start <= linend)
  680.     {
  681.         bufgo(start++);
  682.         n = bufgetln(linebuf,MAXLEN);
  683.         n = min(n,MAXLEN);
  684.         if (pushline(file,linebuf,n) != ERR) {
  685.             pmtlnx();
  686.             continue;
  687.             }
  688.         sysclose(file);
  689.         bufgo(oldline);
  690.         return(ERR);
  691.     }
  692.     /* close the file */
  693.     sysclose(file);
  694.     bufgo(oldline);
  695.     return(OK);
  696. }
  697.  
  698. /* substitute default arguments if none given */
  699. default(args,defltarg)
  700. char    *args,*defltarg;
  701. {
  702.     args=skipbl(skiparg(args));
  703.     if (*args != EOS) return;
  704.     *args++ = ' ';
  705.     while(*defltarg != EOS){*args++ = *defltarg++;}
  706.     *args = EOS;
  707. }
  708.  
  709.  
  710. /* end module ed3/ccc */
  711.  
  712.  
  713.  
  714.  
  715.